package sleuthkit.util;

import java.io.File;

import org.apache.log4j.Logger;

public class Node {

	private Logger log = Logger.getLogger(Node.class);
	private String name;
	private File nodesFile;
	private File imageFile;
	private String slot;
	private int startoffset;
	private int type;
	private int endoffset;
	private int length;
	private String description;
	private String flsType;
	private String id;
	public static final int IMAGE_FILE = 0;
	public static final int PARTITION_TABLE_ENTRY = 1;
	public static final int DIRECTORY = 2;
	public static final int FILE = 3;

	public Node(String name, File nodesFile) {
		super();
		this.name = name;
		this.nodesFile = nodesFile;
	}

	public Node(File file) {
		name = file.getName();
		nodesFile = file;
	}

	public Node(String line) {
		this.name = line;
		nodesFile = null;
	}

	/**
	 * 
	 * @param name
	 * @param type  what kind of Node this is.
	 * 				0 = imagefile
	 * 				1 = partition table entry 
	 * 				2 = directory
	 * 				3 = file/link
	 * @param line
	 */
	public Node(String namn, int type, String line) {
		this.type = type;
		this.name = namn;
		if (type == 1) {
			parsePartition(line);
		}
	}

	
	/**
	 * 
	 * @param name
	 * @param type what kind of Node this is.
	 * 				0 = imagefile
	 * 				1 = partition table entry 
	 * 				2 = directory
	 * 				3 = file/link
	 * @param line
	 * @param imageFile	the "source" file for this node. This is the root image file that contained the partian and file system.
	 */
	public Node(String name, int type, String line, File imageFile) {
		super();
		this.name = name;
		this.imageFile = imageFile;
		this.type = type;
		if (type == 1){
			parsePartition(line);
		}
	}

	public Node(Node parent, String flsType, String id, String name) {
		this.name = parent.name;
		log.debug("setting this.name = " +parent.name);
		this.nodesFile = parent.nodesFile;
		log.debug("setting this.nodesFile = " +parent.nodesFile);
		this.imageFile = parent.imageFile;
		log.debug("setting this.imageFile = " +parent.imageFile);
		this.slot = parent.slot;
		log.debug("setting this.slot = " +parent.slot);
		this.startoffset = parent.startoffset;
		log.debug("setting this.startoffset = " +parent.startoffset);
		this.type = parent.type;
		log.debug("setting this.type = " +parent.type);
		this.endoffset = parent.endoffset;
		log.debug("setting this.endoffset = " + parent.endoffset);
		this.length = parent.length;
		log.debug("setting this.length = " +parent.length);
		this.description = parent.description;
		log.debug("setting this.description = " +parent.description);

		this.name = name;
		log.debug("setting this.name = " +name);
		this.flsType = flsType;
		log.debug("setting this.flsType = "+flsType);
		this.id = id;
		log.debug("setting this.id = "+id);
	}

	/**
	 * function to parse out the information given by mmls
	 * 
	 * @param line
	 *            a line of output from mmls
	 */
	private void parsePartition(String line) {
		/*
		 * Slot Start End Length Description 00: Meta 0000000000 0000000000
		 * 0000000001 Primary Table (#0) 01: ----- 0000000000 0000000062
		 * 0000000063 Unallocated 02: 00:00 0000000063 0009510479 0009510417
		 * NTFS (0x07) 03: ----- 0009510480 0009514259 0000003780 Unallocated
		 */
		log.debug("inside parsePartition");
		log.debug("line = " + line);
		int indexColon = line.indexOf(":");
		log.debug("indexColon = " + indexColon);
		slot = line.substring(5, 12).trim();
		log.debug("Slot = " + slot);
		startoffset = Integer.parseInt(line.substring(13, 23).trim());
		log.debug("Start = " + startoffset);
		endoffset = Integer.parseInt(line.substring(23, 36).trim());
		log.debug("End = " + endoffset);
		length = Integer.parseInt(line.substring(36, 49).trim());
		log.debug("Length = " + length);
		description = line.substring(49).trim();
		log.debug("description = \"" + description + "\"");

	}

	/**
	 * Function to test if this node is of a imagefile type.
	 * 
	 * @return true if and only if this node is of type imagefile
	 */
	public boolean isImageFile() {
		return type == IMAGE_FILE;
	}

	public boolean isPartitionEntry() {
		return type == PARTITION_TABLE_ENTRY;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		if (nodesFile == null) {
			return name;
		} else {
			return name + " (" + nodesFile.toString() + ")";
		}
	}

	/**
	 * @return the name
	 */
	protected String getName() {
		log.debug("getName");
		return name;
	}

	/**
	 * @param name
	 *            the name to set
	 */
	protected void setName(String name) {
		log.debug("setName");
		this.name = name;
	}

	/**
	 * @return the nodesFile
	 */
	public File getNodesFile() {
		log.debug("getNodesFile");
		return nodesFile;
	}

	/**
	 * @param nodesFile
	 *            the nodesFile to set
	 */
	protected void setNodesFile(File nodesFile) {
		log.debug("setNodesFile");
		this.nodesFile = nodesFile;
	}

	public boolean hasFile() {
		return nodesFile != null;
	}

	public boolean fileEquals(File file) {
		return nodesFile.equals(file);
	}

	/**
	 * @return the log
	 */
	public Logger getLog() {
		return log;
	}

	/**
	 * @return the slot
	 */
	public String getSlot() {
		return slot;
	}

	/**
	 * @return the startoffset
	 */
	public int getStartoffset() {
		return startoffset;
	}

	/**
	 * @return the type
	 */
	public int getType() {
		return type;
	}

	/**
	 * @return the endoffset
	 */
	public int getEndoffset() {
		return endoffset;
	}

	/**
	 * @return the length
	 */
	public int getLength() {
		return length;
	}

	/**
	 * @return the description
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * @return the imageFile
	 */
	public File getImageFile() {
		return imageFile;
	}

	/**
	 * @param imageFile the imageFile to set
	 */
	public void setImageFile(File imageFile) {
		this.imageFile = imageFile;
	}

	/**
	 * @param log the log to set
	 */
	public void setLog(Logger log) {
		this.log = log;
	}

	/**
	 * @param slot the slot to set
	 */
	public void setSlot(String slot) {
		this.slot = slot;
	}

	/**
	 * @param startoffset the startoffset to set
	 */
	public void setStartoffset(int startoffset) {
		this.startoffset = startoffset;
	}

	/**
	 * @param type the type to set
	 */
	public void setType(int type) {
		this.type = type;
	}

	/**
	 * @param endoffset the endoffset to set
	 */
	public void setEndoffset(int endoffset) {
		this.endoffset = endoffset;
	}

	/**
	 * @param length the length to set
	 */
	public void setLength(int length) {
		this.length = length;
	}

	/**
	 * @param description the description to set
	 */
	public void setDescription(String description) {
		this.description = description;
	}

	public boolean isDirectory() {
		return flsType.equalsIgnoreCase("d/d");
	}

	/**
	 * @return the flsType
	 */
	public String getFlsType() {
		return flsType;
	}

	/**
	 * @param flsType the flsType to set
	 */
	public void setFlsType(String flsType) {
		this.flsType = flsType;
	}

	/**
	 * @return the id
	 */
	public String getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(String id) {
		this.id = id;
	}

	
	
}
